package com.wicket.okrframework.biz.service.nb;


import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSONArray;
import com.wicket.okrcomponent.common.annotations.BanAuto;
import com.wicket.okrcomponent.integration.FwCompTemplateEngineClient;
import com.wicket.okrcomponent.integration.dto.QuerySemanticEngineDetailReqDto;
import com.wicket.okrcomponent.integration.dto.QuerySemanticEngineDetailRespDto;
import com.wicket.okrframework.biz.service.dto.req.CheckCaptchaValidReqDto;
import com.wicket.okrframework.biz.service.dto.res.CheckCaptchaValidRespDto;
import com.wicket.okrframework.common.redis.PublicInfoForRedis;
import com.wicket.okrframework.common.util.CommonFunctionHelper;
import com.wicket.okrframework.common.util.RedisUtil;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.apache.skywalking.apm.toolkit.trace.Tag;
import org.apache.skywalking.apm.toolkit.trace.Tags;
import org.apache.skywalking.apm.toolkit.trace.Trace;
import org.springframework.stereotype.Service;
import com.wicket.okrframework.biz.service.dto.req.QueryReceiveFieldDetailReqDto;
import com.wicket.okrframework.biz.service.dto.res.QueryReceiveFieldDetailRespDto;
import com.wicket.okrframework.biz.service.dto.req.CalculationMethodReqDto;
import com.wicket.okrframework.biz.service.dto.res.CalculationMethodRespDto;
import com.wicket.okrframework.biz.service.dto.req.GenerateTokenReqDto;
import com.wicket.okrframework.biz.service.dto.res.GenerateTokenRespDto;
import com.wicket.okrframework.biz.service.dto.req.ClearTokenFromRedisReqDto;
import com.wicket.okrframework.biz.service.dto.res.ClearTokenFromRedisRespDto;
import com.wicket.okrframework.biz.service.dto.req.PutPublicInfoToRedisReqDto;
import com.wicket.okrframework.biz.service.dto.res.PutPublicInfoToRedisRespDto;
import com.wicket.okrframework.biz.service.dto.req.AutoAenerateSemanticContentReqDto;
import com.wicket.okrframework.biz.service.dto.res.AutoAenerateSemanticContentRespDto;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import com.wicket.okrframework.biz.service.dto.req.ImplementAuthLoginOutReqDto;
import com.wicket.okrframework.biz.service.dto.res.ImplementAuthLoginOutRespDto;
import com.wicket.okrframework.biz.service.dto.req.ObtainAuthAccountInfoReqDto;
import com.wicket.okrframework.biz.service.dto.res.ObtainAuthAccountInfoRespDto;
import com.wicket.okrframework.biz.service.dto.req.ImplementObtainUnifiedAuthenticationLoginInformationReqDto;
import com.wicket.okrframework.biz.service.dto.res.ImplementObtainUnifiedAuthenticationLoginInformationRespDto;

/**
 * @author ： 手工接入方法
 * @since 2022/5/28 15:32
 *
 *
 * @version 1.0
 */
@Service
public class NbUser {

    @Resource
    private RedisUtil redisClient;

    @Resource
    private FwCompTemplateEngineClient fwCompTemplateEngineClient;
    /**
     * code:checkCaptchaValid
     * name:M-检测验证码是否有效（特殊方法）
     * desc:undefined
     **/
    @BanAuto
    @Trace(operationName = "M-检测验证码是否有效（特殊方法）")
    @Tags({@Tag(key = "参数", value = "arg[0]"),
            @Tag(key = "返回值", value = "returnedObj")})
    public CheckCaptchaValidRespDto checkCaptchaValid(CheckCaptchaValidReqDto reqDto) {
        CheckCaptchaValidRespDto retData = new CheckCaptchaValidRespDto();
        retData.setIsInvalid("FALSE");
        return retData;
    }
/**
      * code:getPublicFieldCache
      * name:M1-获取接收字段（特殊方法）
      * desc:undefined
      * gen by moon at 8/17/2022, 8:01:09 PM
      * 
      **/
     @Trace(operationName = "M1-获取接收字段（特殊方法）")
     @Tags({@Tag(key = "参数",value = "arg[0]"),
     @Tag(key = "返回值",value = "returnedObj")})
      public QueryReceiveFieldDetailRespDto queryReceiveFieldDetail(QueryReceiveFieldDetailReqDto reqDto) {
         QueryReceiveFieldDetailRespDto retData =  BeanUtil.toBean(reqDto,QueryReceiveFieldDetailRespDto.class);
         return retData;
      }
/**
      * code:calculationMethod
      * name:M-计算方法（特殊方法）
      * desc:undefined
      * gen by moon at 8/25/2022, 6:28:03 AM
      * 
      **/
     @Trace(operationName = "M-计算方法（特殊方法）")
     @Tags({@Tag(key = "参数",value = "arg[0]"),
     @Tag(key = "返回值",value = "returnedObj")})
      public CalculationMethodRespDto calculationMethod(CalculationMethodReqDto reqDto) {
         CalculationMethodRespDto retData = new CalculationMethodRespDto();
         Date currentDate = CommonFunctionHelper.getCurrentTime();
         Long span = currentDate.getTime() - reqDto.getLastLockoutTime().getTime();
         span = span/1000;
         if(span > reqDto.getThresholdValue().longValue()){
             retData.setIsInvalid("TRUE");
         }else{
             retData.setIsInvalid("FALSE");
         }
        return retData;
      }
/**
      * code:generateToken
      * name:M-生成Token（特殊方法）
      * desc:undefined
      * gen by moon at 8/25/2022, 6:28:19 AM
      * 
      **/
     @Trace(operationName = "M-生成Token（特殊方法）")
     @Tags({@Tag(key = "参数",value = "arg[0]"),
     @Tag(key = "返回值",value = "returnedObj")})
      public GenerateTokenRespDto generateToken(GenerateTokenReqDto reqDto) {
         GenerateTokenRespDto retData =  new GenerateTokenRespDto();
         retData.setToken(UUID.randomUUID().toString().replaceAll("-", ""));
        return retData;
      }
/**
      * code:clearTokenFromRedis
      * name:M-Redis清空用户Token（特殊方法）
      * desc:undefined
      * gen by moon at 8/25/2022, 6:28:20 AM
      * 
      **/
     @Trace(operationName = "M-Redis清空用户Token（特殊方法）")
     @Tags({@Tag(key = "参数",value = "arg[0]"),
     @Tag(key = "返回值",value = "returnedObj")})
      public ClearTokenFromRedisRespDto clearTokenFromRedis(ClearTokenFromRedisReqDto reqDto) {
         String token = (String) redisClient.get("登录令牌"+":"+"token-" + reqDto.getOriginalRoleMemberId());
         if (token == null || token.isEmpty()) {
             return new ClearTokenFromRedisRespDto();
         }
         redisClient.delete("登录令牌"+":"+token);
         redisClient.delete("登录令牌"+":"+"token-" + reqDto.getOriginalRoleMemberId());
         return new ClearTokenFromRedisRespDto();
      }
/**
      * code:putPublicInfoToRedis
      * name:M-公共信息存储Redis（特殊方法）
      * desc:undefined
      * gen by moon at 8/25/2022, 6:28:21 AM
      * 
      **/
     @Trace(operationName = "M-公共信息存储Redis（特殊方法）")
     @Tags({@Tag(key = "参数",value = "arg[0]"),
     @Tag(key = "返回值",value = "returnedObj")})
      public PutPublicInfoToRedisRespDto putPublicInfoToRedis(PutPublicInfoToRedisReqDto reqDto) {
         try {
             PublicInfoForRedis info = BeanUtil.toBean(reqDto, PublicInfoForRedis.class);
             Object jo = JSONArray.toJSON(info);
             redisClient.set("登录令牌"+":"+"token-" + info.getOriginalRoleMemberId(), reqDto.getToken());
             redisClient.set("登录令牌"+":"+reqDto.getToken(), jo.toString(),3600L, TimeUnit.SECONDS);
         } catch (Exception ex) {
         }
         return new PutPublicInfoToRedisRespDto();
      }
/**
      * code:generateSemanticInstance
      * name:M1-自动生成语义内容（男士）
      * desc:undefined
      * gen by moon at 8/27/2022, 5:46:11 PM
      * 
      **/
     @Trace(operationName = "M1-自动生成语义内容（男士）")
     @Tags({@Tag(key = "参数",value = "arg[0]"),
     @Tag(key = "返回值",value = "returnedObj")})
      public AutoAenerateSemanticContentRespDto autoAenerateSemanticContent(AutoAenerateSemanticContentReqDto reqDto) {
         boolean bRetFlag = false;
         AutoAenerateSemanticContentRespDto retData = new AutoAenerateSemanticContentRespDto();
         String retConent = "";
         QuerySemanticEngineDetailReqDto querySemanticEngineDetailReqDto = new QuerySemanticEngineDetailReqDto();
         querySemanticEngineDetailReqDto.setTemplateSemanticEngineCode("FORGOT_PWD_RESET_NOTICE");
         QuerySemanticEngineDetailRespDto querySemanticEngineDetailRespDto = fwCompTemplateEngineClient.querySemanticEngineDetail(querySemanticEngineDetailReqDto).getData();
         if(querySemanticEngineDetailRespDto!=null && querySemanticEngineDetailRespDto.getTemplateEngineTemplate()!=null){
             String idCardName = "\\{idCardName}";
             String userRespectName = "\\{userRespectName}";
             if(reqDto.getIdCardName()!=null && !reqDto.getIdCardName().isEmpty()){
                 bRetFlag = true;
                 retConent = querySemanticEngineDetailRespDto.getTemplateEngineTemplate().replaceAll(idCardName,reqDto.getIdCardName());
             }else{
                 retConent = querySemanticEngineDetailRespDto.getTemplateEngineTemplate().replaceAll(idCardName,"---");
             }

             if(reqDto.getUserRespectName()!=null && !reqDto.getUserRespectName().isEmpty()){
                 retConent = retConent.replaceAll(userRespectName,reqDto.getUserRespectName());
             }else{
                 retConent = retConent.replaceAll(userRespectName,"---");
             }



             if(retConent!=null && !retConent.isEmpty()){
                 retConent = retConent.replaceAll("---","");
                 retConent = retConent.replaceAll("（）","");
                 retData.setObjectName(retConent);
             }

             if(bRetFlag){
                 return retData;
             }

         }
         return retData;
      }
/**
      * code:implementAuthLoginOut
      * name:M1-执行统一认证退出登录（特殊方法）
      * desc:undefined
      * gen by moon at 9/12/2023, 7:56:17 PM
      *
      **/
     @Trace(operationName = "M1-执行统一认证退出登录（特殊方法）")
     @Tags({@Tag(key = "参数",value = "arg[0]"),
     @Tag(key = "返回值",value = "returnedObj")})
      public ImplementAuthLoginOutRespDto implementAuthLoginOut(ImplementAuthLoginOutReqDto reqDto) {
         ImplementAuthLoginOutRespDto retData = new ImplementAuthLoginOutRespDto();
         String url = CommonFunctionHelper.constructRedirectUrl(reqDto.getAuthLogoutUrl(),"service",reqDto.getAuthLoginUrl());
         retData.setAuthLoginUrl(url);
         return retData;
      }

      private Map<String, String> extractReqValues(ObtainAuthAccountInfoReqDto req){
          Map<String, String> retData = new HashMap<>();
          Field[] declaredFields = req.getClass().getDeclaredFields();
          for (Field field : declaredFields) {
              if(!field.getName().contains("Field")){
                  continue;
              }
              field.setAccessible(true);
              String value = null;
              try {
                  value = (String)field.get(req);
                  if(value!=null){
                      retData.put(field.getName(),value);
                  }
              } catch (IllegalAccessException e) {
                  e.printStackTrace();
              }
          }
          return retData;
      }

      private Map<String, Field> extractRetField(ObtainAuthAccountInfoRespDto req){
          Map<String, Field> retData = new HashMap<>();
          Field[] declaredFields = req.getClass().getDeclaredFields();
          for (Field field : declaredFields) {
              field.setAccessible(true);
              retData.put(field.getName()+"Field",field);
          }
          return retData;
      }

    /**
     * code:obtainAuthAccountInfo
     * name:M1-调用统一认证接口（特殊方法）
     * desc:undefined
     * gen by moon at 9/12/2023, 7:56:35 PM
     *
     **/
      @Trace(operationName = "M1-调用统一认证接口（特殊方法）")
      @Tags({@Tag(key = "参数",value = "arg[0]"),
      @Tag(key = "返回值",value = "returnedObj")})
      public String getCasInfo(String ticketUrl){
          String responseBody = "";
          OkHttpClient client = new OkHttpClient();
          try {

              Request request = new Request.Builder()
                      .url(ticketUrl)
                      .build();
              Response response = client.newCall(request).execute();
              responseBody = response.body().string();
          } catch (Exception e) {
              e.printStackTrace();
          }
          return responseBody;
      }

/**
      * code:obtainAuthAccountInfo
      * name:M1-获取统一认证用户信息（特殊方法）
      * desc:undefined
      * gen by moon at 9/12/2023, 7:56:35 PM
      *
      **/
     @Trace(operationName = "M1-获取统一认证用户信息（特殊方法）")
     @Tags({@Tag(key = "参数",value = "arg[0]"),
     @Tag(key = "返回值",value = "returnedObj")})
      public ObtainAuthAccountInfoRespDto obtainAuthAccountInfo(ObtainAuthAccountInfoReqDto reqDto) {
         ObtainAuthAccountInfoRespDto retData = new ObtainAuthAccountInfoRespDto();
         Map<String, String> reqValues = extractReqValues(reqDto);
         Map<String, Field> retFields = extractRetField(retData);


         String service = reqDto.getAppCallBackUrl();
         String ticketUrl = reqDto.getAuthCheckTicketUrl() + "serviceValidate?ticket=" + reqDto.getAuthTicket() + "&service=" + service;
         String responseBody = getCasInfo(ticketUrl);

         redisClient.set("获取统一认证用户信息报文",responseBody);

         for(Map.Entry<String,String> oneReq :reqValues.entrySet()){
             Field target = retFields.get(oneReq.getKey());
             if(target!=null){
                 int startIndex = responseBody.indexOf(oneReq.getValue()) + oneReq.getValue().length();
                 if(startIndex==-1){
                     continue;
                 }
                 int endIndex = responseBody.indexOf(oneReq.getValue().replace("<cas:", "</cas:"));
                 if(endIndex==-1){
                     continue;
                 }
                 String targetValue = responseBody.substring(startIndex, endIndex).trim();
                 try {
                     target.set(retData,targetValue);
                 } catch (IllegalAccessException e) {
                     e.printStackTrace();
                 }
             }
         }

        return retData;
      }
/**
      * code:splicingUnifiedAuthenticationAddresses
      * name:M1拼第三方统一认证的登录地址（特殊方法）
      * desc:undefined
      * gen by moon at 12/20/2023, 9:17:40 PM
      *
      **/
     @Trace(operationName = "M1拼第三方统一认证的登录地址（特殊方法）")
     @Tags({@Tag(key = "参数",value = "arg[0]"),
     @Tag(key = "返回值",value = "returnedObj")})
      public ImplementObtainUnifiedAuthenticationLoginInformationRespDto implementObtainUnifiedAuthenticationLoginInformation(ImplementObtainUnifiedAuthenticationLoginInformationReqDto reqDto) {
         ImplementObtainUnifiedAuthenticationLoginInformationRespDto retData = new ImplementObtainUnifiedAuthenticationLoginInformationRespDto();
         String url = CommonFunctionHelper.constructRedirectUrl(reqDto.getAuthLoginUrl(),"service",reqDto.getAppCallBackUrl(),false,false);
         retData.setSplicingAuthAddresses(url);
         return retData;
      }
    //手工接入方法
}
